/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.nifi.processors.huawei.common;

import org.apache.nifi.components.AllowableValue;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.expression.ExpressionLanguageScope;
import org.apache.nifi.processor.util.StandardValidators;
import org.apache.nifi.processors.huawei.dli.DLIUtils;
import org.apache.nifi.processors.huawei.obs.OBSRegions;
import org.apache.nifi.processors.huawei.credentials.provider.service.HuaweiCredentialsProviderService;
import org.apache.nifi.processors.huawei.obs.Constants;
import org.apache.nifi.processors.huawei.obs.ObsServiceEncryptionService;
import org.apache.nifi.processors.huawei.smn.SMNUtils;
import org.apache.nifi.proxy.ProxyConfiguration;
import org.apache.nifi.ssl.SSLContextService;

import java.util.stream.Collectors;

public interface PropertyDescriptors {
    PropertyDescriptor ACCESS_KEY = new PropertyDescriptor.Builder()
            .name("Access Key")
            .displayName("Access Key ID")
            .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
            .required(false)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .sensitive(true)
            .build();

    PropertyDescriptor SECRET_KEY = new PropertyDescriptor.Builder()
            .name("Secret Key")
            .displayName("Secret Access Key")
            .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
            .required(false)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .sensitive(true)
            .build();
     PropertyDescriptor PROXY_HOST = new PropertyDescriptor.Builder()
            .name("Proxy Host")
            .description("Proxy host name or IP")
            .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
            .required(false)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .build();

    PropertyDescriptor PROXY_HOST_PORT = new PropertyDescriptor.Builder()
            .name("Proxy Host Port")
            .description("Proxy host port")
            .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
            .required(false)
            .addValidator(StandardValidators.PORT_VALIDATOR)
            .build();

    PropertyDescriptor PROXY_USERNAME = new PropertyDescriptor.Builder()
            .name("proxy-user-name")
            .displayName("Proxy Username")
            .description("Proxy username")
            .required(false)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .build();

    PropertyDescriptor PROXY_PASSWORD = new PropertyDescriptor.Builder()
            .name("proxy-user-password")
            .displayName("Proxy Password")
            .description("Proxy password")
            .required(false)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .sensitive(true)
            .build();

    PropertyDescriptor OBS_REGION = new PropertyDescriptor.Builder()
            .name("OBS Region")
            .description("If the destination Region is Not found, select Not Found and enter the Endpoint address of the destination Region in the Endpoint Override URL box")
            .required(true)
            .allowableValues(OBSRegions.getAvailableOBSRegions())
            .defaultValue(OBSRegions.DEFAULT_REGION.getName())
            .build();
    PropertyDescriptor ENDPOINT_OVERRIDE_URL = new PropertyDescriptor.Builder()
            .name("Endpoint Override URL")
            .description("The endpoint specified in this option box takes effect only when the OBS Region option is Not found")
            .required(false)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .build();
    PropertyDescriptor TIMEOUT = new PropertyDescriptor.Builder()
            .name("Communications Timeout")
            .required(true)
            .addValidator(StandardValidators.TIME_PERIOD_VALIDATOR)
            .defaultValue("30 secs")
            .build();

    PropertyDescriptor SSL_CONTEXT_SERVICE = new PropertyDescriptor.Builder()
            .name("SSL Context Service")
            .description("Specifies an optional SSL Context Service that, if provided, will be used to create connections")
            .required(false)
            .identifiesControllerService(SSLContextService.class)
            .build();
    /**
     * Huawei credentials provider service
     */
    PropertyDescriptor HUAWEI_CREDENTIALS_PROVIDER_SERVICE = new PropertyDescriptor.Builder()
            .name("Huawei Credentials Provider service")
            .displayName("Huawei Credentials Provider Service")
            .description("The Controller Service that is used to obtain huawei credentials provider")
            .required(false)
            .identifiesControllerService(HuaweiCredentialsProviderService.class)
            .build();
     PropertyDescriptor DELIMITER = new PropertyDescriptor.Builder()
            .name("delimiter")
            .displayName("Delimiter")
            .expressionLanguageSupported(ExpressionLanguageScope.NONE)
            .required(false)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .description("Specifies the character used to group the object name. " +
                    "The grouping steps are as follows: " +
                    "① First select all object names that contain this Delimiter; " +
                    "② Remove the prefix field from the object names. (If the prefix field is not specified in the request, skip this step.) " +
                    "③ Group by the string between the first character and Delimiter (later returned as CommonPrefix).")
            .build();

     PropertyDescriptor PREFIX = new PropertyDescriptor.Builder()
            .name("prefix")
            .displayName("Prefix")
            .expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
            .required(false)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .description("The prefix used to filter the object list. In most cases, it should end with a forward slash ('/').")
            .build();
     PropertyDescriptor WRITE_USER_METADATA = new PropertyDescriptor.Builder()
            .name("write-obs-user-metadata")
            .displayName("Write User Metadata")
            .description("If set to 'True', the user defined metadata associated with the OBS object will be added to FlowFile attributes/records")
            .required(true)
            .allowableValues(new AllowableValue("true", "True"), new AllowableValue("false", "False"))
            .defaultValue("false")
            .build();
    PropertyDescriptor FULL_CONTROL_USER_LIST = new PropertyDescriptor.Builder()
            .name("FullControl User List")
            .required(false)
            .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .description("A comma-separated list of huaweiCloud account ID's that specifies who should have Full Control for an object")
            .defaultValue("${obs.permissions.full.users}")
            .build();

    PropertyDescriptor READ_USER_LIST = new PropertyDescriptor.Builder()
            .name("Read Permission User List")
            .required(false)
            .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .description("A comma-separated list of huaweiCloud account ID's that specifies who should have Read Access for an object")
            .defaultValue("${obs.permissions.read.users}")
            .build();
   PropertyDescriptor READ_ACL_LIST = new PropertyDescriptor.Builder()
            .name("Read ACL User List")
            .required(false)
            .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .description("A comma-separated list of huaweiCloud account ID's that specifies who should have permissions to read the Access Control List for an object")
            .defaultValue("${obs.permissions.readacl.users}")
            .build();
    PropertyDescriptor WRITE_ACL_LIST = new PropertyDescriptor.Builder()
            .name("Write ACL User List")
            .required(false)
            .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .description("A comma-separated list of huaweiCloud account ID's that specifies who should have permissions to change the Access Control List for an object")
            .defaultValue("${obs.permissions.writeacl.users}")
            .build();
    PropertyDescriptor CANNED_ACL = new PropertyDescriptor.Builder()
            .name("canned-acl")
            .displayName("Canned ACL")
            .required(false)
            .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .description("OBS Canned ACL for an object, one of: Private, PublicRead, PublicReadWrite, PublicReadWriteDelivered; " +
                    "will be ignored if any other ACL/permission/owner property is specified; details: https://support.huaweicloud.com/sdk-java-devg-obs/obs_21_0406.html")
            .defaultValue("${obs.permissions.cannedacl}")
            .build();

    PropertyDescriptor OWNER = new PropertyDescriptor.Builder()
            .name("Owner")
            .required(false)
            .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .description("The huaweiCloud Account ID to use for the object's owner")
            .defaultValue("${obs.owner}")
            .build();
    PropertyDescriptor BUCKET = new PropertyDescriptor.Builder()
            .name("Bucket")
            .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
            .required(true)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .build();
    PropertyDescriptor KEY = new PropertyDescriptor.Builder()
            .name("Object Key")
            .required(true)
            .addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
            .expressionLanguageSupported(ExpressionLanguageScope.FLOWFILE_ATTRIBUTES)
            .defaultValue("${filename}")
            .build();
    PropertyDescriptor ENCRYPTION_SERVICE = new PropertyDescriptor.Builder()
            .name("encryption-service")
            .displayName("Encryption Service")
            .description("Specifies the Encryption Service Controller used to configure requests. " +
                    "PutOBSObject/FetchOBSObject: Only needs to be configured in case of Server-side SSE_KMS/SSE_C encryption")
            .required(false)
            .identifiesControllerService(ObsServiceEncryptionService.class)
            .build();
    PropertyDescriptor PROXY_CONFIGURATION_SERVICE = ProxyConfiguration.createProxyConfigPropertyDescriptor(false, Constants.PROXY_SPECS);
    PropertyDescriptor SMN_REGION = new PropertyDescriptor.Builder()
            .name("SMN Region")
            .description("If the destination Region is Not found, select Not Found and enter the Endpoint address of the destination Region in the Endpoint Override URL box")
            .required(true)
            .allowableValues(SMNUtils.getAvailableRegions().stream()
                    .map(x -> new AllowableValue(x.getId(), x.getId(), x.getId())).collect(Collectors.toList())
                    .toArray(new AllowableValue[0]))
            .build();
    PropertyDescriptor DLI_REGION = new PropertyDescriptor.Builder()
            .name("DLI Region")
            .description("Indicates the region where the API is currently available.")
            .required(true)
            .allowableValues(DLIUtils.getAvailableRegions().stream()
                    .map(x -> new AllowableValue(x.getId(), x.getId(), x.getId())).collect(Collectors.toList())
                    .toArray(new AllowableValue[0]))
            .build();
}
